package com.tevintao.marketingsystem.xposted;

import android.accounts.AccountManager;
import android.os.Process;
import android.telephony.TelephonyManager;

import com.tevintao.marketingsystem.log.LogManager;

import java.io.IOException;

import de.robv.android.xposed.XC_MethodHook;


public class HookRuntimeCommand {
    private static HookRuntimeCommand ourInstance = new HookRuntimeCommand();

    public static HookRuntimeCommand getInstance() {
        return ourInstance;
    }

    private HookRuntimeCommand() {
    }

    private Class[] mHookAllCls = {AccountManager.class, TelephonyManager.class};

    public void hookCommand() {
        HookDeviceModule.hookAllMethodByName(Runtime.class, "exec", mRunTimeHook);
        HookDeviceModule.hookAllMethodByName(Runtime.class, "load", mRunTimeHook);
        HookDeviceModule.hookAllMethodByName(Runtime.class, "loadLibrary", mRunTimeHook);
        HookDeviceModule.hookAllMethodByName(ProcessBuilder.class, "start", mRunTimeHook);
        HookDeviceModule.hookAllMethodByName(Process.class, "startViaZygote", mRunTimeHook);
    }


    private XC_MethodHook mRunTimeHook = new XC_MethodHook() {

        @Override
        protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
            try {
                if (param.thisObject instanceof Runtime) {
                    String name = param.method.getName();
                    if ("exec".equals(name)) {
                        param.setThrowable(new IOException("Runtime before error"));
                        LogManager.getInstance().logInfo("hookCommand after  Runtime = " + " method = " + name + " args = " + getArgsStr(param.args));
                    } else if ("load".equals(name)) {
                    } else if ("loadLibrary".equals(name)) {
                    }
                }

                if (param.thisObject instanceof ProcessBuilder) {
                    param.setThrowable(new IOException("ProcessBuilder before error"));
                }

                if (param.thisObject instanceof Process) {
                    param.setThrowable(new Exception("Process before error"));
                    LogManager.getInstance().logInfo("hookCommand before  Process = " + " method = " + param.method + " args = " + getArgsStr(param.args));
                }
            } catch (Throwable ex) {
                LogManager.getInstance().logHookError("hookCommand before Throwable " + ex.getMessage() + " method = " + param.method);
            }
        }
    };

    public static String getArgsStr(Object[] args) {
        StringBuffer sb = new StringBuffer();
        for (Object o : args) {
            sb.append(o.getClass().getSimpleName() + ":" + o.toString());
            sb.append(" | ");
        }
        return sb.toString();
    }


}
